#ifndef LCOM_HEAP_H
#define LCOM_HEAP_H

/** Heap
 */
typedef struct Heap_ *Heap;

/** Assinatura das funções de comparação usadas em heaps
 *
 * \param o1 Primeiro objecto
 * \param o2 Segundo objecto
 * \returns Um valor negativo se o1 tem maior prioridade que o2, 0 se a prioridade de ambos é igual ou positivo se a prioridade de o2 é maior que a de o1
 */
typedef int (* heapCmpFunc) (void *o1, void *o2);

/** \brief Cria um novo heap
 * \param func Função de comparação
 * \returns Um novo heap
 */
Heap heap_new (heapCmpFunc func);

/** \brief Destroi um heap
 * \param heap Heap a ser removido
 */
void heap_delete (Heap heap);

/** \brief Adiciona um novo elemento ao heap
 * \param heap Heap
 * \param el elemento
 */
void heap_push (Heap heap, void * el);

/** \brief Remove o elemento no topo do heap
 * \param heap Heap
 * \returns O elemento do topo ou NULL se o heap está vazio
 */
void *heap_pop (Heap heap);

/** Diz o tamanho do heap
 * \param heap Heap
 * \return O tamanho do heap
 */
int heap_size (Heap heap);

/** Assinatura das funções usadas em heap_forall
 *
 * \param el Objecto no heap
 */
typedef void (* HeapForallFunc) (void *el, void *data);

/** Aplica uma função a todos os elementos do heap
 */
void heap_forall (Heap heap, HeapForallFunc func, void *data);

/** Remove um elemento do heap
 */
void heap_remove (Heap heap, void *el);

#endif /* LCOM_HEAP_H */

